package com.fr.base.file;

import com.fr.base.FRContext;
import com.fr.base.XMLFileManager;
import com.fr.base.cache.CacheEventAdapter;
import com.fr.base.cache.CacheException;
import com.fr.base.cache.FRCache;
import com.fr.base.cache.RegisteredEventListeners;
import com.fr.base.cache.Unity;
import com.fr.base.cache.config.CacheConfiguration;
import com.fr.base.cache.store.MemoryStore;
import com.fr.base.cache.store.Status;
import com.fr.base.xml.XMLPrintWriter;
import com.fr.base.xml.XMLReadable;
import com.fr.base.xml.XMLableReader;
import com.fr.data.impl.DBTableData;
import com.fr.data.impl.DatabaseConnection;
import com.fr.data.impl.TableDataAdapter;
import com.fr.report.io.xml.SynchronizedVersion;
import com.fr.util.Consts;
import com.fr.util.Utils;
import java.io.File;
import java.util.logging.Level;
import java.util.logging.Logger;

public class CacheManager extends XMLFileManager
{
  private File cacheDirectory = null;
  private int maxMemSize = 4194304;
  private CacheConfiguration dbConfig = new CacheConfiguration();
  private CacheConfiguration cptConfig = new CacheConfiguration();
  private Thread shutdownHook;
  private Status status = Status.STATUS_UNINITIALISED;
  private FRCache db_cache;
  private FRCache cpt_cache;
  private boolean alwaysReloadTpl = true;

  public CacheManager()
  {
    addShutdownHookIfRequired();
    this.db_cache = createDBCache();
    this.cpt_cache = createCptCache();
  }

  public String fileName()
  {
    return "cache.xml";
  }

  public synchronized TableDataAdapter get(DatabaseConnection paramDatabaseConnection, String paramString, long paramLong)
  {
    TableDataAdapter localTableDataAdapter = (TableDataAdapter)this.db_cache.getObject(new DBKey(paramDatabaseConnection, paramString));
    if (localTableDataAdapter == null)
    {
      localTableDataAdapter = DBTableData.createCacheableAdapter(paramDatabaseConnection, paramString, 0, paramLong);
      this.db_cache.put(new DBKey(paramDatabaseConnection, paramString), localTableDataAdapter);
    }
    return localTableDataAdapter;
  }

  public File getCacheDirectory()
  {
    if (this.cacheDirectory == null)
    {
      this.cacheDirectory = new File(Consts.getEnvHome(), "cache");
      Utils.mkdirs(this.cacheDirectory);
      this.cacheDirectory.deleteOnExit();
    }
    return this.cacheDirectory;
  }

  public int getMaxMemSize()
  {
    return this.maxMemSize;
  }

  public void setMaxMemSize(int paramInt)
  {
    this.maxMemSize = paramInt;
  }

  public CacheConfiguration getDbConfig()
  {
    return this.dbConfig;
  }

  public void setDbConfig(CacheConfiguration paramCacheConfiguration)
  {
    this.dbConfig = paramCacheConfiguration;
  }

  public CacheConfiguration getCptConfig()
  {
    return this.cptConfig;
  }

  public void setCptConfig(CacheConfiguration paramCacheConfiguration)
  {
    this.cptConfig = paramCacheConfiguration;
  }

  public void setAlwaysReloadTpl(boolean paramBoolean)
  {
    this.alwaysReloadTpl = paramBoolean;
  }

  public boolean isAlwaysReloadTpl()
  {
    return this.alwaysReloadTpl;
  }

  public FRCache createDBCache()
  {
    FRCache localFRCache = new FRCache(this.dbConfig);
    localFRCache.getCacheEventNotificationService().registerListener(new CacheEventAdapter(this, localFRCache)
    {
      private final FRCache val$db_cache;
      private final CacheManager this$0;

      public void notifyElementRemoved(, Unity paramUnity)
        throws CacheException
      {
        TableDataAdapter localTableDataAdapter = (TableDataAdapter)paramUnity.getObjectValue();
        try
        {
          localTableDataAdapter.tryDestroy();
        }
        catch (Exception localException)
        {
          throw new CacheException(localException.getMessage(), localException);
        }
      }

      public void notifyElementExpired(, Unity paramUnity)
      {
        TableDataAdapter localTableDataAdapter = (TableDataAdapter)paramUnity.getObjectValue();
        try
        {
          localTableDataAdapter.tryDestroy();
        }
        catch (Exception localException)
        {
          throw new CacheException(localException.getMessage(), localException);
        }
      }

      public void dispose()
      {
        MemoryStore localMemoryStore = this.val$db_cache.getStore();
        Object[] arrayOfObject = localMemoryStore.getKeyArray();
        for (int i = 0; i < arrayOfObject.length; ++i)
        {
          Unity localUnity = localMemoryStore.get(arrayOfObject[i]);
          TableDataAdapter localTableDataAdapter = (TableDataAdapter)localUnity.getObjectValue();
          try
          {
            localTableDataAdapter.tryDestroy();
          }
          catch (Exception localException)
          {
            throw new CacheException(localException.getMessage(), localException);
          }
        }
      }
    });
    return localFRCache;
  }

  public FRCache createCptCache()
  {
    this.cptConfig.setMemoryStoreEvictionPolicy("DISK_CPT");
    this.cptConfig.setMaxElementsOnDisk(100);
    FRCache localFRCache = new FRCache(this.cptConfig);
    localFRCache.getCacheEventNotificationService().registerListener(new CacheEventAdapter(this)
    {
      private final CacheManager this$0;

      public void dispose()
      {
        if (CacheManager.access$000(this.this$0) != null)
          Utils.deleteFile(CacheManager.access$000(this.this$0));
      }
    });
    return localFRCache;
  }

  public void readXML(XMLableReader paramXMLableReader)
  {
    if (paramXMLableReader.isChildNode())
    {
      String str1;
      Object localObject;
      String str2 = paramXMLableReader.getTagName();
      if (str2.equals("XMLVersion"))
        if ((str1 = paramXMLableReader.getElementValue()) != null)
        {
          localObject = SynchronizedVersion.getSynchronizedVersion(Thread.currentThread());
          ((SynchronizedVersion)localObject).setXmlVersionByString(str1);
        }
      else if ("Basic".equals(str2))
        if ((str1 = paramXMLableReader.getAttr("maxMemSize")) != null)
          setMaxMemSize(Integer.parseInt(str1));
      else if ("DBConfig".equals(str2))
        if (this.dbConfig == null)
        {
          localObject = new CacheConfiguration();
          paramXMLableReader.readXMLObject((XMLReadable)localObject);
          setDbConfig((CacheConfiguration)localObject);
        }
        else
        {
          paramXMLableReader.readXMLObject(getDbConfig());
        }
      else if ("AlwaysReloadTpl".equals(str2))
        setAlwaysReloadTpl(Boolean.valueOf(paramXMLableReader.getElementValue()).booleanValue());
      else if ("CPTConfig".equals(str2))
        if (getCptConfig() == null)
        {
          localObject = new CacheConfiguration();
          paramXMLableReader.readXMLObject((XMLReadable)localObject);
          setDbConfig((CacheConfiguration)localObject);
        }
        else
        {
          paramXMLableReader.readXMLObject(getCptConfig());
        }
    }
  }

  public void writeXML(XMLPrintWriter paramXMLPrintWriter)
  {
    paramXMLPrintWriter.startTAG("CacheParameters");
    paramXMLPrintWriter.startTAG("Basic").attr("maxMemSize", getMaxMemSize()).end();
    if (this.dbConfig != null)
    {
      paramXMLPrintWriter.startTAG("DBConfig");
      this.dbConfig.writeXML(paramXMLPrintWriter);
      paramXMLPrintWriter.end();
    }
    if (this.cptConfig != null)
    {
      paramXMLPrintWriter.startTAG("CPTConfig");
      this.cptConfig.writeXML(paramXMLPrintWriter);
      paramXMLPrintWriter.end();
    }
    paramXMLPrintWriter.startTAG("AlwaysReloadTpl").textNode(String.valueOf(isAlwaysReloadTpl())).end();
    paramXMLPrintWriter.end();
  }

  private void addShutdownHookIfRequired()
  {
    int i = 1;
    if (i == 0)
      return;
    3 local3 = new Thread(this)
    {
      private final CacheManager this$0;

      public void run()
      {
        synchronized (this)
        {
          if (CacheManager.access$100(this.this$0).equals(Status.STATUS_ALIVE))
          {
            CacheManager.access$202(this.this$0, null);
            this.this$0.shutdown();
          }
        }
      }
    };
    Runtime.getRuntime().addShutdownHook(local3);
    this.shutdownHook = local3;
  }

  private void removeShutdownHook()
  {
    if (this.shutdownHook != null)
    {
      try
      {
        Runtime.getRuntime().removeShutdownHook(this.shutdownHook);
      }
      catch (IllegalStateException localIllegalStateException)
      {
        FRContext.getLogger().log(Level.WARNING, "IllegalStateException due to attempt to remove a shutdownhook while the VM is actually shutting down.", localIllegalStateException);
      }
      this.shutdownHook = null;
    }
  }

  public void shutdown()
  {
    synchronized (CacheManager.class)
    {
      if (!(this.status.equals(Status.STATUS_SHUTDOWN)))
        break label40;
      return;
      label40: if (this.db_cache == null)
        break label54;
      this.db_cache.dispose();
      label54: Utils.deleteFile(this.cacheDirectory);
      this.status = Status.STATUS_SHUTDOWN;
      removeShutdownHook();
    }
  }

  static File access$000(CacheManager paramCacheManager)
  {
    return paramCacheManager.cacheDirectory;
  }

  static Status access$100(CacheManager paramCacheManager)
  {
    return paramCacheManager.status;
  }

  static Thread access$202(CacheManager paramCacheManager, Thread paramThread)
  {
    return (paramCacheManager.shutdownHook = paramThread);
  }

  private static abstract interface PoolKey
  {
  }

  private static class DBKey
    implements CacheManager.PoolKey
  {
    private DatabaseConnection database;
    private String query;

    public DBKey(DatabaseConnection paramDatabaseConnection, String paramString)
    {
      this.database = paramDatabaseConnection;
      this.query = paramString;
    }

    public int hashCode()
    {
      return (this.database.hashCode() + this.query.hashCode());
    }

    public boolean equals(Object paramObject)
    {
      if (!(paramObject instanceof DBKey))
        return false;
      DBKey localDBKey = (DBKey)paramObject;
      return ((this.database.equals(localDBKey.database)) && (this.query.equals(localDBKey.query)));
    }
  }
}